"""
 Retrieves Feedburner Awareness Data in RSS format
 
 @example /srv/s4/feed-id/
 @author Jean-Lou Dupont
"""
import os
import sys
import logging

import wsgiref.handlers
import xml.dom.minidom
import time
from time import strftime, strptime

from google.appengine.ext           import webapp
#from google.appengine.ext.webapp    import template
from libs.wiki import template
from google.appengine.api           import urlfetch

class Service_S4( webapp.RequestHandler ):
    """
    Service_S4: Feedburner Awareness Data
    
    Usage:  /srv/s4/feed-id/
            where "feed-id" would match: http://feeds.feedburner.com/feed-id/
    """
    
    api = 'http://api.feedburner.com/awareness/1.0/GetFeedData?uri=http://feeds.feedburner.com/%s';
    
    def __init__(self):
        pass

    def head(self, feed_id):
        user_agent = self.request.headers['User-Agent']
        
        try:    if_modified_since = self.request.headers['If-Modified-Since']
        except: if_modified_since = ''
        
        try:    if_none_match     = self.request.headers['If-None-Match']
        except: if_none_match     = ''        
        
        logging.info( "FeedId [%s] UA[%s]" % (feed_id, user_agent) )
        logging.info( "HEAD request: If-Modified-Since (%s), If-None-Match (%s)" %  (if_modified_since, if_none_match) )
        
        [rawPage, page] = self.getPage( feed_id )
        if page is None:
            self.response.set_status( 404 );
            return
        
        params = self.extractParams( feed_id, rawPage, page )
        self.response.headers['ETag'] = '"' + params[ 'etag' ] + '"'
        self.response.headers['Last-Modified'] = params[ 'itemPubDate' ]
        self.response.headers['Content-Type'] = "application/rss+xml"
        self.response.set_status( 200 );  

    def get( self, feed_id ):
        
        user_agent = self.request.headers['User-Agent']
        
        try:     if_modified_since = self.request.headers['If-Modified-Since']
        except:  if_modified_since = ''
        try:     if_none_match     = self.request.headers['If-None-Match']
        except:  if_none_match     = ''
        
        logging.info( "FeedId [%s] UA[%s]" % (feed_id, user_agent) )
        logging.info( "GET request: FeedId (%s) If-Modified-Since (%s), If-None-Match (%s)" %  (feed_id, if_modified_since, if_none_match) )
        
        [rawPage, page] = self.getPage( feed_id )
        if page is None:
            return
        
        params = self.extractParams( feed_id, rawPage, page )
        self.printPage( params )

    def getRawPage(self, feed_id ):
        rawPage = None
        page = None
        try:
            rawPage = urlfetch.fetch( self.api % feed_id )
            if ( rawPage.status_code != 200 ):
                return None
        except:
            return None
        return rawPage
    
    def getPage( self, feed_id ):
        rawPage = self.getRawPage(feed_id)
        if (rawPage is None):
            return [None,None];
        page = xml.dom.minidom.parseString( rawPage.content )
        return [ rawPage.content, page ]

    def extractParams( self, feed_id, rawPage, page ):
        feed = page.getElementsByTagName( 'feed' )
        if feed is None:
            return None
        
        id   = feed[0].getAttribute( 'id' )
        uri   = feed[0].getAttribute( 'uri' )
        entry= feed[0].getElementsByTagName( 'entry' )
        date = entry[0].getAttribute( 'date' )
        circ = entry[0].getAttribute( 'circulation' )
        hits = entry[0].getAttribute( 'hits' )
        reach= entry[0].getAttribute( 'reach' )

        link = 'http://feeds.feedburner.com/%s' % uri

        sDate   = strptime( date, "%Y-%m-%d" )
        pubDate = strftime( "%a, %d %b %Y %H:%M:%S +0000", sDate )
        pubTime = strftime( "%H:%M:%S", time.localtime() )

        params = {  'feed_id': feed_id,
                    'itemTitle' : uri,
                    'itemLink' : link,
                    'itemCirculation': circ, 
                    'itemHits':hits, 
                    'itemReach':reach, 
                    'itemPubDate': pubDate,
                    'rawData' : rawPage,
                    'etag': pubDate,
                    'itemGuid': uri + '-' + date + '-' + pubTime
                }
        return params 

    def printPage(self, params ):
        # Path to the template
        path = os.path.join(os.path.dirname(__file__), 'template.xml')
        
        self.response.headers['ETag'] = '"' + params[ 'etag' ] + '"'
        self.response.headers['Last-Modified'] = params[ 'itemPubDate' ]
        self.response.headers['Content-Type'] = "application/rss+xml"
        self.response.set_status( 200 );
        
        # template replacement & rendering
        self.response.out.write(template.render( path, params ))

    def aw(self):
        """
            <?xml version="1.0" encoding="UTF-8"?>
            <rsp stat="ok">
              <feed id="1433336" uri="jldupont/Mediawiki">
                <entry date="2008-05-06" circulation="9" hits="70" reach="0" />
              </feed>
            </rsp>
        """
        pass

#/**
# *  Initialize http handler
# */
def main():
  application = webapp.WSGIApplication([('/services/feedburner/aw/(.*?)/', Service_S4)], debug=True)
  wsgiref.handlers.CGIHandler().run(application)

# Bootstrap
#  It all starts here
if __name__ == "__main__":
    main()